<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\manage\model;

use buwang\base\BaseModel;
use buwang\traits\JwtTrait;
use think\facade\Validate;
use app\manage\model\Member;
use app\common\model\User;
use app\common\model\MemberMiniapp;
use buwang\exception\MiniappException;
use buwang\util\Util;
use app\Request;
use think\facade\Db;
use buwang\util\Sql;

/**配置表
 * Class BwAuthNode
 * @package app\manage\model
 */
class Config extends BaseModel
{

    use JwtTrait;

    protected $pk = 'id';
    // 表名
    protected $table = 'bw_sys_config';
    protected $updateTime = '';

    protected $deleteTime = '';


    /*
* 设置查询初始化条件
* @param string $alias 表别名
* @param object $model 模型实例化对象
* @return object
* */
    public static function valiWhere($alias = '', $model = null, $dir = '', $show = true)
    {
        if ($dir) {
            $model = is_null($model) ? self::getAppConfigModel($dir) : $model;
            if (!$model) throw new MiniappException("该应用配置表缺失，请创建{$dir}的配置表");
        } else {
            $model = is_null($model) ? new self() : $model;
        }
        if ($alias) {
            $model = $model->alias($alias);
            $alias .= '.';
        }
        if ($show) $model = $model->where("{$alias}status", 0);
        return $model;
    }


    /**得到配置基础查询条件
     * @param $memberId
     * @param $scopes
     * @param $Dir
     * @return Config
     */
    public static function getConfigBaseWhere($memberId, $scopes, $Dir, $app = false)
    {
        if ($app && $Dir) {
            $model = self::getAppConfigModel($Dir); //从相关应用中取
        } else {
            $model = new self;
        }
        if (!$model) return false;
        $model = $model->where('scopes', 'in', $scopes);
        if ($memberId !== null) {
            $model = $model->where(function ($query) use ($memberId) {
                $query->where(function ($query) use ($memberId) {
                    $query->where('scopes', 'member')->where('member_id', 'in', [$memberId]);
                })->whereOr(function ($query) use ($memberId) {
                    $query->where('scopes', 'common')->where('member_id', 0);
                });
            });
        }
        //如果存在应用配置则优先取应用配置
        if ($Dir) {
            $model = $model->orderRaw("dir='{$Dir}' desc,member_id desc");
        }
        return $model;
    }

    /**得到数据组基础查询条件
     * @param $Dir
     */
    public static function getConfigTabBaseWhere($Dir, $app = false)
    {
        if ($app && $Dir) {
            $ConfigTabModel = self::getAppConfigTabModel($Dir); //从相关应用中取
        } else {
            $ConfigTabModel = new ConfigTab;
        }
        if (!$ConfigTabModel) return false;
        //如果存在应用配置则优先取应用配置
        if ($Dir) {
            $ConfigTabModel = $ConfigTabModel->orderRaw("dir='{$Dir}' desc");
        }
        return $ConfigTabModel;
    }


    /**
     * 得到基础的配置查询结果（根据不同表数据源查询）
     */
    public static function getBaseQueryResult($name, $memberId, $scopes, $Dir, &$multipart, $app = false)
    {
        $ConfigTabModel = self::getConfigTabBaseWhere($Dir, $app);
        $model = self::getConfigBaseWhere($memberId, $scopes, $Dir, $app);
        if (!$model || !$ConfigTabModel) return false;

        //判断是单取还是取整个数组
        $multipart = false;//默认单取
        $config_info = null;
        $names = explode('.', $name);
        if (count($names) > 1) {
            //先查出来tab
            $ConfigTab = $ConfigTabModel->where('tab_name', $names[0])->find();
            if ($ConfigTab) {
                if ($ConfigTab['dir']) $model = $model->where('dir', $ConfigTab['dir']);//TODO:2021/4/21 查询配置只依赖标识，不依赖id
                $config_info = $model->where('config_name', $names[1])->where('tab_name', $ConfigTab['tab_name'])->where('scopes', $ConfigTab['scopes'])->find();
            }
        } else {
            $config_info = $model->where('config_name', $name)->fetchSql(false)->find();
            if (!$config_info) {
                $config_info = $ConfigTabModel->where('tab_name', $name)->find();
                if ($config_info) $multipart = true;
            }
        }

        if (!$config_info) return false;
        $configs = array();
        //取组数据
        if ($multipart) {
            $model = self::getConfigBaseWhere($memberId, $scopes, $Dir, $app);
            if ($config_info['dir']) $model = $model->where('dir', $config_info['dir']);//TODO:2021/4/21 查询配置只依赖标识，不依赖id
            $configs = $model->where('tab_name', $config_info['tab_name'])->where('scopes', $config_info['scopes'])->select()->toArray();
        } else {
            //取单数据
            $configs[] = $config_info;
        }
        if (!$configs) return false;
        return $configs;
    }


    public static function config($name, $default = null, $member_id = null, $dir = null)
    {
        //得到登录信息
        $jwtinfo = null;
        $topuser = null;
        $scopes = ['common', 'member'];
        $memberId = $member_id;
        $Dir = $dir;
        $configs = false;
        //判断是单取还是取整个数组
        $multipart = false;//默认单取
        //如果存在应用标识优先
        if ($Dir) {
            //先从对应应用中去取
            $configs = self::getBaseQueryResult($name, $memberId, $scopes, $Dir, $multipart, true);
        }
        //如果应用中没有再从系统中去取
        if (!$configs) $configs = self::getBaseQueryResult($name, $memberId, $scopes, $Dir, $multipart);
        if (!$configs) return $default;

        $values = array();
        foreach ($configs as $config) {

            $value = htmlspecialchars_decode($config['value']);
            if ($value === null || $value === '' || $value === '[]' || $value === '{}') {
                //取组数据则记录每个元素默认值
                if ($multipart) {
                    $values[$config['config_name']] = $default;
                    continue;
                } else {
                    //单取数据返回默认值
                    return $default;
                }
            }

            //如果类型是数字或时间戳，则转成int
            if ($config['input_type'] == 'number' || $config['input_type'] == 'timestamp') {
                if ($value) {
                    $value = intval($value);
                } else {
                    $value = 0;
                }
            }
            //如果类型是小数，则转换成浮点
            if ($config['input_type'] == 'float') {
                if ($value) {
                    $value = floatval($value);
                } else {
                    $value = floatval('0.00');
                }
            }

            //如果是富文本或多文本，需要htmi反转移
            //if($config['type']=='r_textarea'||$config['type']=='textarea')$value =htmlspecialchars_decode($value);
            //如果类型是文件上传，返回数组
            if ($config['type'] == 'upload') {
                $upload_date = json_decode($value, true);//json串传数组
                if ($upload_date) {
                    $value = $upload_date;
                } else {
                    $value = [];
                };
            }
            //复选框多值返回数组
            if ($config['type'] == 'checkbox') {
                //如果是多值，转换成数组(限定条件，只能是：多选框)
                if (is_string($value) && count(explode(',', $value)) > 1) {
                    $value = explode(',', $value);
                }
            }
            $values[$config['config_name']] = $value;
        }
        //$new=array_shift($a);
        if ($multipart) {
            return $values;
        } else {
            //取单数据
            return array_shift($values);
        }

    }

    /**前端需要展示的配置数据
     * @param $tab_name
     * @param $type
     */
    public static function getShowData($tab_name = null, $type = null, $member_id = null, $scopes = 'common', $config_ids = null, $dir = null)
    {
        //返回数据
        $data = array();
        $sort = 'sort desc,id desc';
        //查询所有tab
        $ConfigTab = ConfigTab::valiWhere('', null, $dir);
        if ($tab_name) $ConfigTab = $ConfigTab->where('tab_name|id', 'in', $tab_name);
        if ($type) $ConfigTab = $ConfigTab->where('type', 'in', $type);
        if ($scopes) $ConfigTab = $ConfigTab->where('scopes', $scopes);
        if ($dir) $ConfigTab = $ConfigTab->where('dir', $dir);
        $ConfigTabs = $ConfigTab->order($sort)->select()->toArray();

        if (!$ConfigTabs) return $data;
        if ($config_ids) {
            if (!is_array($config_ids) && !is_string($config_ids) && !is_int($config_ids)) return $data;
            if (is_int($config_ids)) $config_ids = (string)$config_ids;
        }
        //租户初始配置字段ids
        $init_member_configs = array();
        $init_member_config_names = array();
        if ($scopes && $scopes == 'member') {
            //如果需要查租户的则需要判断
            // 1如果没传租户id但是租户登录则从租户信息里取租户id
            $token = get_token(app("app\Request"));
            $jwtinfo = null;
            if ($token) $jwtinfo = self::decodeToken($token);//解析token,获取用户信息
            //根据登录情况判断取配置值的权限
            if ($jwtinfo) {
                //租户登录 取顶级租户配置
                if ($jwtinfo->scopes == 'member' && !$member_id) {
                    $topuser = Member::getTop($jwtinfo->data->id);
                    if ($topuser && isset($topuser['id'])) $member_id = $topuser['id'];
                }
                if ($jwtinfo->scopes == 'admin' && $member_id) {
                    $topuser = Member::getTop($member_id);
                    if ($topuser && isset($topuser['id'])) $member_id = $topuser['id'];
                }

            } elseif ($member_id) {
                $topuser = Member::getTop($member_id);
                if ($topuser && isset($topuser['id'])) $member_id = $topuser['id'];
            }
            // 2如果既不是租户登录，也没传租户id，却要查租户配置列表则不予通过
            if (!$member_id) return $data;

        }
        /**2020 07 22 配置懒加载，如果租户无该配置则渲染初始化配置  start**/
        if ($member_id) {
            //得到全部的租户配置id和字段，并以配置字段为key 配置id为值
            $init_member_configs = self::valiWhere('', null, $dir)->where('member_id', 0)->where('scopes', 'member')->column('id', 'config_name');
            $init_member_config_names = self::valiWhere('', null, $dir)->where('member_id', 0)->where('scopes', 'member')->column('config_name');//所有租户基础配置标识
        }
        /**2020 07 22 配置懒加载，如果租户无该配置则渲染初始化配置  end**/
        //遍历tab
        foreach ($ConfigTabs as $ConfigTab) {

            $ConfigTab['config_list'] = [];
            $selfModel = self::valiWhere('', null, $dir)->where('tab_name', $ConfigTab['tab_name']);
            if ($scopes) $selfModel = $selfModel->where('scopes', $scopes);
            if ($config_ids) $selfModel = $selfModel->where('id|config_name', 'in', $config_ids);
            if ($member_id) $selfModel = $selfModel->where('member_id', $member_id);
            if ($dir) $selfModel = $selfModel->where('dir', $dir);
            //查询所有tab下的配置
            $configs = $selfModel->order('sort desc,id desc')->select()->toArray();
            /**2020 07 22 配置懒加载，如果租户无该配置则渲染初始化配置  start**/
            if ($member_id && $init_member_config_names && $init_member_configs) {
                $configNames = array();//得到当前租户拥有的该分类下的全部配置标识
                $configIds = array();//查出来的所有的配置id
                $init_config_ids = array();//需要渲染的初始化配置id
                foreach ($configs as $conf) {
                    $configNames[] = $conf['config_name'];
                    $configIds[] = $conf['id'];
                }
                $diff_config_names = array_diff($init_member_config_names, $configNames); //对当前租户拥有的配置标识和所有租户基础配置标识取差集，得到租户缺少的初始化配置
                //遍历差集得到需要渲染的初始化配置ids
                foreach ($diff_config_names as $diff_config_name) {
                    $init_config_ids[] = $init_member_configs[$diff_config_name];//初始化配置id
                }
                if ($init_config_ids) {
                    $init_config_ids = array_merge($init_config_ids, $configIds);//合并两个数组
                    //查询初始化的配置，并合并到之前的租户配置数组中
                    $init_config_model = self::valiWhere('', null, $dir)->where('id', 'in', $init_config_ids)->where('tab_name', $ConfigTab['tab_name']);
                    if ($scopes) $init_config_model = $init_config_model->where('scopes', $scopes);
                    if ($config_ids) $init_config_model = $init_config_model->where('id|config_name', 'in', $config_ids);
//                    if ($member_id) $init_config_model = $init_config_model->where('member_id', $member_id);
                    if ($dir) $init_config_model = $init_config_model->where('dir', $dir);

                    $configs = $init_config_model->order('sort desc,id desc')->select()->toArray();
                }

            }

            /**2020 07 22 配置懒加载，如果租户无该配置则渲染初始化配置  end**/
            //分类下有配置的才渲染
            if ($configs) {
                //$configs  = array_values($configs);
                //处理多行文本域转移字符
                foreach ($configs as &$config) {
                    //如果是租户初始化配置则无默认值
                    if ($config['member_id'] == 0 && $config['scopes'] == 'member') $config['value'] = null;
                    $config['files'] = [];
                    //拼装字段数据
                    $config['label_name'] = '{$' . $ConfigTab['tab_name'] . '.' . $config['config_name'] . '}';
                    if ($config['type'] == 'r_textarea' || $config['type'] == 'textarea') {
                        $config['value'] = htmlspecialchars_decode($config['value']);
                    }
                    //处理单选框和多选框和下拉框
                    if ($config['type'] == 'radio' || $config['type'] == 'checkbox' || $config['type'] == 'select') {
                        $parameter = htmlspecialchars_decode($config['parameter']);

                        $parameter = explode("\n", $parameter);
                        $datas = array();
                        foreach ($parameter as $value) {
                            $value = explode("=>", $value);
                            $datas[] = [
                                'key' => $value[0],
                                'value' => $value[1],
                            ];

                        }
                        $config['parameter'] = $datas;

                    }

                    //处理文件上传
                    if ($config['type'] == 'upload') {
                        switch ($config['upload_type']) {
                            case 1: //单图
                                //var_dump($config['value']);die;
                                $config['value'] = htmlspecialchars_decode($config['value']);
                                if ($config['value']) {
                                    $upload_date = json_decode($config['value'], true);//json串传数组
                                    if ($upload_date) {
                                        $config['files'] = $upload_date;
                                        $config['value'] = $upload_date['src'];
                                    }
                                }

                                break;
                            case 2: //多图
                                $config['value'] = htmlspecialchars_decode($config['value']);
                                if ($config['value']) {
                                    $upload_date = json_decode($config['value'], true);//json串传数组
                                    if ($upload_date) {
                                        $config['files'] = $upload_date;
                                        $config['value'] = implode(",", array_column($upload_date, 'src'));
                                    }
                                }


                                break;
                            case 3: //文件
                                $config['value'] = htmlspecialchars_decode($config['value']);
                                if ($config['value']) {
                                    $upload_date = json_decode($config['value'], true);//json串传数组
                                    if ($upload_date) {
                                        $config['files'] = $upload_date;
                                    }
                                }
                                break;
                        }

                    }
                }
                $ConfigTab['config_list'] = $configs;

                $data[] = $ConfigTab;
            }

        }
        return $data;
    }

    /**更改配置数据
     * @param array $param
     */
    public static function setValues($params = [], $member_id = 0, $scopes = 'common', $trans = false)
    {
        if (isset($params['app'])) $dir = $params['app']; else $dir = null;
        unset($params['file']);
        unset($params['app']);
        //需要更新的数据
        $update_data = array();
        //验证规则数据
        $rule = array();
        //验证提示数据
        $message = array();
        //待验证数据
        $validate_list = array();
        //取出所用的数据
        if (!$params) return true;
        if ($scopes && $scopes == 'member') {
            $memberData = Util::getLoginMemberId($member_id);
            $member_id = $memberData['memberId'];
            // 2如果既不是租户登录，也没传租户id，却要查租户配置列表则不予通过
            if (!$member_id) return self::setError('条件不足，无法查出租户的配置');
        }
        //空值判断
        foreach ($params as $k => $v) {
            if ($v === '' || $v === null) return self::setError('提交数据中，字段【' . $k . '】值为空，无法提交');
        }
        //组装提交数据
        foreach ($params as $param_name => $param_value) {
            $configModel = self::valiWhere('', null, $dir, false);
            if ($member_id) $configModel = $configModel->where('member_id', $member_id);
            if ($scopes) $configModel = $configModel->where('scopes', $scopes);
            if ($dir) $configModel = $configModel->where('dir', $dir);
            //查询该参数名的数据
            $config = $configModel->where('config_name', $param_name)->find();
            /**  2020 07 22 租户配置懒加载，只在提交变更值的时候插入该数据 start**/
            if ($member_id) {
                //如果租户不存在该字段数据则先插入数据
                if (!$config) {
                    //查询租户原始数据看是否存在
                    $baseConfig = self::valiWhere('', null, $dir, false)->where('member_id', 0)->where('scopes', 'member')->where('config_name', $param_name);
                    if ($dir) $baseConfig = $baseConfig->where('dir', $dir);
                    $base_config = $baseConfig->find();
                    //不存在基础配置也报错
                    if (!$base_config) return self::setError('提交数据中，字段【' . $param_name . '】对应的字段配置数据不存在');
                    //插入租户配置，返回该配置实例
                    $base_config = $base_config->toArray();
                    if (!$base_config) return self::setError('提交数据中，字段【' . $param_name . '】对应的字段配置数据异常');
                    //根据初始配置创建子租户配置，返回配置实例
                    $base_config['member_id'] = $member_id;
                    unset($base_config['id']);//新增去掉id

                    $configModel = self::valiWhere('', null, $dir, false);

                    $config = $configModel->save($base_config);
                    if (!$config) return self::setError('提交数据中，字段【' . $param_name . '】对应的字段配置数据不存在');
                    $config = $configModel;
                }
            } else {
                //如果member_id不传则查询的是基础配置，基础配置不存在则报错
                if (!$config) return self::setError('提交数据中，字段【' . $param_name . '】对应的字段配置数据不存在');
            }
            /**  2020 07 22 配置懒加载，只在需要的时候加载他 start**/
            //如果是文本值查看是否有验证规则
            if ($config['type'] == 'text') {
                //测试是否有文本
                if ($config['input_type'] == 'text' || $config['input_type'] == 'number' || $config['input_type'] == 'float') {
                    //如果有规则加上
                    if ($config['rule']) {
                        $config['rule'] = htmlspecialchars_decode($config['rule']);
                        $rule[$config['config_name'] . '|' . $config['info']] = $config['rule'];
                        $validate_list[$param_name] = $param_value;
                        //查看是否有验证提示
                        if ($config['message']) {
                            $config['message'] = htmlspecialchars_decode($config['message']);
                            $config['message'] = explode('|', $config['message']);
                            foreach ($config['message'] as $value) {
                                $value = explode('=>', $value);
                                if (count($value) != 2) return self::setError('提交数据中，字段【' . $param_name . '】对应的验证提示配置不正确');
                                $message[$value[0]] = $value[1];
                            }
                        }
                    }
                }
                //日期类型转时间戳
                if ($config['input_type'] == 'timestamp') $param_value = strtotime($param_value);
            }
            //如果是多选框得到拼接值
            if ($config['type'] == 'checkbox') {
                $param_value = implode(",", $param_value);//数组合并成字符串;
            }
            //如果是富文本先反转移
            if ($config['type'] == 'r_textarea') {
                $param_value = Util::r_text_decode($param_value);
            }
            //如果是上传则查询出上传信息
            if ($config['type'] == 'upload') {
                //单图
                if ($config['upload_type'] == '1') {
                    //{"name":"透明.png","size":172692,"type":"image/png","src":"http://www.bwsaas.com/upload/20201103\\4848bd71e499aacb95990527c365d45d.png"}
                    //如果不是json格式的图片则查询上传管理塞进json格式
                    $upload_json = json_decode($param_value, true);//json串传数组
                    if (!$upload_json) {
                        //查询上传信息
                        $upload_file = \app\common\model\SysUploadfile::where('url', $param_value)->find();
                        if ($upload_file) {
                            $param_value = json_encode([
                                'name' => $upload_file['original_name'],
                                'size' => $upload_file['file_size'],
                                'type' => $upload_file['mime_type'],
                                'src' => $upload_file['url'],
                            ]);
                        } else {
                            if ($param_value) {
                                $param_value = json_encode([
                                    'name' => basename($param_value),
                                    'size' => 0,
                                    'type' => '',
                                    'src' => $param_value,
                                ]);
                            } else {
                                $param_value = null;
                            }
                        }
                    }
                }
                //多图
                if ($config['upload_type'] == '2') {
                    //如果不是json格式的图片则查询上传管理塞进json格式
                    $upload_json = json_decode($param_value, true);//json串传数组
                    if (!$upload_json) {
                        $imgs = explode(',', $param_value);//字符串分割数组
                        //查询上传信息
                        $upload_files = \app\common\model\SysUploadfile::where('url', 'in', $imgs)->select()->toArray();
                        $data = [];
                        if ($upload_file) {
                            foreach ($upload_files as $upload_file) {
                                $data[] = [
                                    'name' => $upload_file['original_name'],
                                    'size' => $upload_file['file_size'],
                                    'type' => $upload_file['mime_type'],
                                    'src' => $upload_file['url'],
                                ];
                            }
                            $param_value = json_encode($data);//数组转json;
                        } else {
                            if ($param_value) {
                                foreach ($imgs as $img) {
                                    $data[] = [
                                        'name' => basename($img),
                                        'size' => 0,
                                        'type' => '',
                                        'src' => $img,
                                    ];
                                }
                                $param_value = json_encode($data);//数组转json;
                            } else {
                                $param_value = null;
                            }
                        }
                    }
                }
            }
            $update_data[] = [
                'id' => $config['id'],
                'value' => $param_value,
            ];
        }
        //待验证的动态验证
        if ($rule) {
            $validate = Validate::rule($rule);
            if ($message) $validate = $validate->message($message);
            if ($validate_list) {
                if (!$validate->check($validate_list)) {
                    return self::setError($validate->getError());
                    //var_dump();die;
                }
            }

        }
        if ($trans) {
            self::startTrans();
        }
        $res = true;
        try {
            $config = self::valiWhere('', null, $dir, false);
            $res = $config->saveAll($update_data);
            $res = $res && true;
            if ($trans) {
                BaseModel::checkTrans($res);
            }
        } catch (\Exception $e) {
            if ($trans) {
                BaseModel::rollback();
            }
            return self::setError($e->getMessage());
        }
        if (!$res) return self::setError('保存失败');

        return $res;


    }


    public static function getEntity($id, $app = '')
    {
        $data = self::valiWhere('', null, $app, false)->find($id);
        if (!$data) return null;
        if ($data['value']) $data['value'] = htmlspecialchars_decode($data['value']);
        if ($data['rule']) $data['rule'] = htmlspecialchars_decode($data['rule']);
        if ($data['message']) $data['message'] = htmlspecialchars_decode($data['message']);
        if ($data['parameter']) $data['parameter'] = htmlspecialchars_decode($data['parameter']);
        return $data;
    }

    /**取租户和总后台配置  $member_id 不传如果是租户或者用户则自动查询租户的配置
     * @return array|mixed
     */
    public static function memberAndAdminConfig($name, $default = null, $member_id = null, $dir = null)
    {
        $memberData = Util::getLoginMemberId($member_id, $dir);
        $memberId = $memberData['memberId'];
        $Dir = $memberData['dir'];
        return self::config($name, $default, $memberId, $Dir);
    }

    /**获取对应应用的配置model
     * @param $dir
     */
    public static function getAppConfigModel($dir)
    {
        $table_prefix = config('database.connections.mysql.prefix');//前缀
        $table_name = "{$table_prefix}{$dir}_config";
        //是否存在该表
        if (!Sql::existTable($table_name)) return false;

        $model_class = "\\app\\{$dir}\\model\\system\\Config";
        //得到应用的model
        if (!class_exists($model_class)) return false;
        set_miniapp_database_prefix($dir);
        return new $model_class();
    }

    /**获取对应应用的配置分类model
     * @param $dir
     */
    public static function getAppConfigTabModel($dir)
    {
        $table_prefix = config('database.connections.mysql.prefix');//前缀
        $table_name = "{$table_prefix}{$dir}_config_tab";
        //是否存在该表
        if (!Sql::existTable($table_name)) return false;
        $model_class = "\\app\\{$dir}\\model\\system\\ConfigTab";
        //得到应用的model
        if (!class_exists($model_class)) return false;
        set_miniapp_database_prefix($dir);
        return new $model_class();
    }


    public static function getTabTableName($dir = '')
    {
        $table_prefix = config('database.connections.mysql.prefix');//前缀
        if ($dir) {
            $table_name = "{$table_prefix}{$dir}_config_tab";
        } else {
            $table_name = "{$table_prefix}sys_config_tab";
        }
        return $table_name;
    }


    //配置和组合数据迁移
    public static function configAndDataMove($dir, $trans = false,$delete= true)
    {
        set_miniapp_database_prefix($dir);
        //TODO: 将系统中的应用配置搬运到应用表中
        //得到框架的配置分类
        $sys_config_tabs = ConfigTab::where('dir', $dir)->where('scopes', 'member')->select()->toArray();
        //得到框架的配置
        $sys_configs = Config::where('dir', $dir)->where('scopes', 'member')->select()->toArray();
        //得到框架的数据组分类
        $sys_config_groups = ConfigGroup::where('dir', $dir)->where('scopes', 'member')->select()->toArray();
        //得到框架的数据组
        $sys_config_group_datas = ConfigGroupData::where('dir', $dir)->where('scopes', 'member')->select()->toArray();

        $app_config_tabs = $app_configs = $app_config_groups = $app_config_group_datas = [];//需移动的数据


        //将框架表中的配置分类移动到应用表
        foreach ($sys_config_tabs as $sys_config_tab) {
            unset($sys_config_tab['id']);
            $app_config_tabs[] = $sys_config_tab;//数据转移
        }
        //将框架表中的配置移动到应用表
        foreach ($sys_configs as $sys_config) {
            unset($sys_config['id']);
            $app_configs[] = $sys_config;//数据转移
        }
        //将框架表中的数据组分类移动到应用表
        foreach ($sys_config_groups as $sys_config_group) {
            unset($sys_config_group['id']);
            $app_config_groups[] = $sys_config_group;//数据转移
        }
        //将框架表中的数据组移动到应用表
        foreach ($sys_config_group_datas as $sys_config_group_data) {
            unset($sys_config_group_data['id']);
            $app_config_group_datas[] = $sys_config_group_data;//数据转移
        }

        if ($trans) {
            Db::startTrans();
        }
        try {
            //清除框架表的应用配置分类
            if ($sys_config_tabs) {
                //数据转移
                ConfigTab::valiWhere('', null, $dir, false)->saveAll($app_config_tabs);
                //框架数据删除
                if($delete)ConfigTab::where('dir', $dir)->where('scopes', 'member')->delete();
            }
            //清除框架表的应用配置
            if ($sys_configs) {
                //数据转移
                Config::valiWhere('', null, $dir, false)->saveAll($app_configs);
                //框架数据删除
                if($delete)Config::where('dir', $dir)->where('scopes', 'member')->delete();
            }
            //清除框架表的数据组分类
            if ($sys_config_groups) {
                //数据转移
                ConfigGroup::valiWhere('', null, $dir)->saveAll($app_config_groups);
                //框架数据删除
                if($delete)ConfigGroup::where('dir', $dir)->where('scopes', 'member')->delete();
            }
            //清除框架表的数据组
            if ($sys_config_group_datas) {
                //数据转移
                ConfigGroupData::valiWhere('', null, $dir)->saveAll($app_config_group_datas);
                //框架数据删除
                if($delete)ConfigGroupData::where('dir', $dir)->where('scopes', 'member')->delete();
            }
            //修正配置id
            $miniappUpdateService = app('buwang\service\MiniappUpdateService'); //应用更新服务类
            $miniappUpdateService->updateConfigAndGroupData($dir);

            if ($trans) {
                Db::commit();
            }
        } catch (\Exception $e) {
            if ($trans) {
                Db::rollback();
            }
            throw new \Exception("更新配置和组合数据失败：" . $e->getMessage().$e->getFile());
        }

        return true;
    }


}
